﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using System.Security.Permissions;
using System.IO;
using System.Collections;
using System.Configuration;
using System.Collections.Concurrent;

namespace Vision.Utilities.ConsoleApp.PreCompilation
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class CmsVirtualDirectory : VirtualDirectory
    {
        const string VirtualDirectoryCacheKeyPrefix = "CmsVirtualDirectory_";
        const string VirtualFileCacheKeyPrefix = "CmsVirtualFile_";
        const string EnableVirtualPathProviderCacheAppSettingKey = "EnableVirtualPathProviderCache";
        /// <summary>
        /// Regularly, we don't need enable this cache.
        /// </summary>
        static readonly bool EnableVirtualPathProviderCache = bool.TrueString.Equals(ConfigurationManager.AppSettings[EnableVirtualPathProviderCacheAppSettingKey], StringComparison.InvariantCultureIgnoreCase);

        #region Ctor
        public CmsVirtualDirectory(string virtualPath)
            : base(virtualPath)
        {
            Init(virtualPath);
        }
        #endregion

        #region Init
        private void Init(string virtualPath)
        {
            if (CmsVirtualPathProvider.IsSpecialPath(virtualPath))
            {
                PhysicalPath = HostingEnvironment.MapPath(virtualPath); 
                if (Directory.Exists(PhysicalPath))
                {
                    exists = true;
                    foreach (var subDirectory in Directory.GetDirectories(PhysicalPath))
                    {
                        var subDirectoryInfo = new DirectoryInfo(subDirectory);
                        var subVirtualPath = VirtualPath + "/" + subDirectoryInfo.Name;

                        var subVirtualDirectoryCachekey = string.Format("{0}{1}", VirtualDirectoryCacheKeyPrefix, subVirtualPath);
                        var subVirtualDirectory = default(CmsVirtualDirectory);
                        if (EnableVirtualPathProviderCache)
                        {
                            subVirtualDirectory = ConfigurationHelper.GetCache(subVirtualDirectoryCachekey) as CmsVirtualDirectory;
                            if (subVirtualDirectory == null)
                            {
                                subVirtualDirectory = new CmsVirtualDirectory(subVirtualPath);
                                ConfigurationHelper.SetCache(subVirtualDirectoryCachekey, subVirtualDirectory, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
                            }
                        }
                        subVirtualDirectory = subVirtualDirectory ?? new CmsVirtualDirectory(subVirtualPath);

                        directories.Add(subVirtualDirectory);
                        children.Add(subVirtualDirectory);
                    }

                    foreach (var subFile in Directory.GetFiles(PhysicalPath))
                    {
                        var subVirtualPath = VirtualPath + "/" + Path.GetFileName(subFile);

                        var subVirtualFileCachekey = string.Format("{0}{1}", VirtualFileCacheKeyPrefix, subVirtualPath);
                        var subVirtualFile = default(CmsVirtualFile);
                        if (EnableVirtualPathProviderCache)
                        {
                            subVirtualFile = ConfigurationHelper.GetCache(subVirtualFileCachekey) as CmsVirtualFile;
                            if (subVirtualFile == null)
                            {
                                subVirtualFile = new CmsVirtualFile(subVirtualPath);
                                ConfigurationHelper.SetCache(subVirtualFileCachekey, subVirtualFile, new System.Web.Caching.CacheDependency(subFile), System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
                            }
                        }
                        subVirtualFile = subVirtualFile ?? new CmsVirtualFile(subVirtualPath);
                        files.Add(subVirtualFile);
                        children.Add(subVirtualFile);
                    }
                }
            }
             
        }
        #endregion

        #region Properties
        protected string PhysicalPath { get; private set; }
        #endregion

        #region Override
        private ArrayList children = new ArrayList();
        public override System.Collections.IEnumerable Children
        {
            get { return children; }
        }
        private ArrayList directories = new ArrayList();
        public override System.Collections.IEnumerable Directories
        {
            get { return directories; }
        }

        private ArrayList files = new ArrayList();
        public override System.Collections.IEnumerable Files
        {
            get { return files; }
        }
        #endregion

        #region Exists
        private bool exists = false;
        public bool Exists
        {
            get { return exists; }
        }
        #endregion

    }
}